package com.spar.openprojects.client.composite;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.spar.openprojects.client.RemoteDataService;
import com.spar.openprojects.client.RemoteDataServiceAsync;
import com.spar.openprojects.shared.Member;
import com.spar.openprojects.shared.Project;

public class ProjectsComposite extends Composite {
	private RemoteDataServiceAsync asyncService = GWT
			.create(RemoteDataService.class);
	private List<Project> projects = new ArrayList<Project>();
	private DecoratorPanel decoratorPanel = new DecoratorPanel();
	private VerticalPanel verticalPanel = new VerticalPanel();
	private CellTable<Project> cellTableProjects = new CellTable<Project>();
	private CheckBox checkboxActive = new CheckBox("Active");
	private Label labelUser = new Label();
	private Member user = new Member();
	private TextColumn<Project> colProjectNumber = new TextColumn<Project>() {
		@Override
		public String getValue(Project project) {
			return project.getNumber().toString();
		}
	};
	private TextColumn<Project> colProjectName = new TextColumn<Project>() {
		@Override
		public String getValue(Project project) {
			return project.getDescription();
		}
	};
	private TextColumn<Project> colProjectResponsible = new TextColumn<Project>() {
		@Override
		public String getValue(Project project) {
			return project.getMember().getLastName();
		}
	};
	private TextColumn<Project> colProjectExternalCostsOrdered = new TextColumn<Project>() {
		@Override
		public String getValue(Project project) {
			return project.getExternalCostsOrdered().toString();
		}
	};
	private TextColumn<Project> colProjectExternalCosts = new TextColumn<Project>() {
		@Override
		public String getValue(Project project) {
			return project.getExternalCosts().toString();
		}
	};
	private Column<Project, Anchor> colProjectInternalDaysUsed = new Column<Project, Anchor>(
			new AnchorCell()) {
		@Override
		public Anchor getValue(Project project) {
			Anchor link = new Anchor();
			if (project.getInternalDaysUsed() > 0) {
				link.setHref(Window.Location.getHost()
						+ "/openprojects/openprojects/etimeexcel?projectId="
						+ project.getId());
				link.setText(project.getInternalDaysUsed().toString());
			}
			return link;
		}

	};
	private TextColumn<Project> colProjectInternalDays = new TextColumn<Project>() {
		@Override
		public String getValue(Project project) {
			return project.getInternalDays().toString();
		}
	};
	private final HorizontalPanel horizontalPanel = new HorizontalPanel();
	private final HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
	private final HorizontalPanel horizontalPanel_2 = new HorizontalPanel();

	private final Label lblProjects = new Label("Projects");

	public ProjectsComposite() {
		checkboxActive.setValue(true);
		cellTableProjects.setPageSize(50);
		decoratorPanel.setWidget(verticalPanel);
		horizontalPanel.setSpacing(10);

		verticalPanel.add(horizontalPanel);
		lblProjects.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);

		horizontalPanel.add(horizontalPanel_1);
		horizontalPanel_1.setWidth("100px");

		horizontalPanel_1.add(lblProjects);
		horizontalPanel_2
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);

		horizontalPanel.add(horizontalPanel_2);
		horizontalPanel_2.setWidth("900px");
		horizontalPanel_2.add(checkboxActive);
		checkboxActive.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				loadProjects(checkboxActive.getValue(), user);
			}
		});
		verticalPanel.add(labelUser);
		verticalPanel.add(cellTableProjects);
		cellTableProjects.setWidth("1000px");

		cellTableProjects.addColumn(colProjectNumber, "Number");
		cellTableProjects.addColumn(colProjectName, "Name");
		cellTableProjects.addColumn(colProjectResponsible, "Responsible");
		cellTableProjects.addColumn(colProjectExternalCostsOrdered,
				"Ext. Costs Ordered");
		cellTableProjects.addColumn(colProjectExternalCosts, "Ext. Costs");
		cellTableProjects.addColumn(colProjectInternalDaysUsed,
				"Int. Days Used");
		cellTableProjects.addColumn(colProjectInternalDays, "Int. Days");

		final SingleSelectionModel<Project> selectionModel = new SingleSelectionModel<Project>();
		cellTableProjects.setSelectionModel(selectionModel);
		selectionModel
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					public void onSelectionChange(SelectionChangeEvent event) {
						RootPanel.get("infoContainer").clear();
						Iterator<Widget> iterator = RootPanel.get(
								"openprojectsContainer").iterator();
						Widget widget;
						// reload orders
						while (iterator.hasNext()) {
							widget = iterator.next();
							if (widget instanceof OrdersComposite) {
								((OrdersComposite) widget).loadOrders(
										(Project) selectionModel
												.getSelectedObject(), user);
							}
						}
						iterator = RootPanel.get("openprojectsContainer")
								.iterator();
						// remove any order edit masks
						while (iterator.hasNext()) {
							widget = iterator.next();
							if (widget instanceof OrderComposite) {
								RootPanel.get("openprojectsContainer").remove(
										widget);
							}
						}

					}
				});

		initWidget(decoratorPanel);

		readUser();
	}

	private void readUser() {
		asyncService.readUser(new AsyncCallback<String>() {

			@Override
			public void onSuccess(String result) {
				user.setNumber(result);
				loadProjects(true, user);
			}

			@Override
			public void onFailure(Throwable caught) {
				RootPanel.get("infoContainer").clear();
				RootPanel.get("infoContainer").add(
						new Label(caught.getMessage()));
				user.setNumber("anonymous");
				loadProjects(true, user);
			}
		});

	}

	public void loadProjects(Boolean active, Member user) {
		loadProjects(active, null, user);
	}

	public void loadProjects(Boolean active, final Project project,
			final Member user) {
		asyncService.getProjects(active, user,
				new AsyncCallback<List<Project>>() {

					@Override
					public void onSuccess(List<Project> result) {
						projects = result;
						if (projects != null) {
							cellTableProjects
									.setRowData(new ArrayList<Project>());
							cellTableProjects.setRowData(projects);
						}
						Iterator<Widget> iterator = RootPanel.get(
								"openprojectsContainer").iterator();
						Widget widget;
						while (iterator.hasNext()) {
							widget = iterator.next();
							if (widget instanceof OrdersComposite) {
								if (project != null)
									((OrdersComposite) widget).loadOrders(
											project, user);
								else
									// load orders of first project in project
									// list
									((OrdersComposite) widget).loadOrders(
											projects.get(0), user);
							}
						}
					}

					@Override
					public void onFailure(Throwable caught) {
						RootPanel.get("infoContainer").clear();
						RootPanel.get("infoContainer").add(
								new Label(caught.getMessage()));
					}
				});

	}

}
